
#include <stdio.h>
#include <string.h>
#include <string>
using namespace std;

const char* types[] = {"Decimal",
                       "Int64",
                       "Int32",
                       "Int16",
                       "SByte",
                       "UInt64",
                       "UInt32",
                       "UInt16",
                       "Byte",
                       "Single",
                       "Double",
                       "String"};

void eva1(FILE* fo)
{
    fputs("        x = y\n"
          "        Return True\n"
          "    End Function\n\n",
          fo);
}

void eva2(FILE* fo)
{
    fputs("        If y Is Nothing Then\n"
          "            Return False\n"
          "        Else\n"
          "            x = y()\n"
          "            Return True\n"
          "        End If\n"
          "    End Function\n\n",
          fo);
}

void eva3(FILE* fo)
{
    fputs("        If Not x Is Nothing Then\n"
          "            x.set(y)\n"
          "        End If\n"
          "        Return True\n"
          "    End Function\n\n",
          fo);
}

void eva4(FILE* fo)
{
    fputs("        If y Is Nothing Then\n"
          "            Return False\n"
          "        Else\n"
          "            If Not x Is Nothing Then\n"
          "                x.set(y())\n"
          "            End If\n"
          "            Return True\n"
          "        End If\n"
          "    End Function\n\n",
          fo);
}

int main(int argc, char* argv[])
{
    if(argc < 2) printf("need a parameter for output file.\n");
    else
    {
        FILE* fo = fopen(argv[1], "w");
        fputs("\n'this file is generated by osi/root/codegen/eva/eva.exe"
              "\n'so edit the osi/root/codegen/eva/eva.cpp instead of this file\n\n"
              "Imports osi.root.formation\n"
              "Imports osi.root.delegates\n"
              "\nPublic Module _eva\n\n", fo);
        for(int i = 0; i < sizeof(types) / sizeof(types[0]); i++)
        {
            string t;
            for(int j = 0; j < 2; j++)
            {
                t = types[i];
                if(j == 1) t += "()";
                fprintf(fo,
                        "    Public Function eva(ByRef x As %s, ByVal y As %s) As Boolean\n",
                        t.c_str(), t.c_str());
                eva1(fo);
                fprintf(fo,
                        "    Public Function eva(ByRef x As %s, ByVal y As _do(Of %s)) As Boolean\n",
                        t.c_str(), t.c_str());
                eva2(fo);
                fprintf(fo,
                        "    Public Function eva(ByRef x As %s, ByVal y As Func(Of %s)) As Boolean\n",
                        t.c_str(), t.c_str());
                eva2(fo);
                fprintf(fo,
                        "    Public Function eva(ByVal x As _pointer(Of %s), ByVal y As %s) As Boolean\n",
                        t.c_str(), t.c_str());
                eva3(fo);
                fprintf(fo,
                        "    Public Function eva(ByVal x As _pointer(Of %s), ByVal y As _do(Of %s)) As Boolean\n",
                        t.c_str(), t.c_str());
                eva4(fo);
                fprintf(fo,
                        "    Public Function eva(ByVal x As _pointer(Of %s), ByVal y As Func(Of %s)) As Boolean\n",
                        t.c_str(), t.c_str());
                eva4(fo);
            }
        }

        fputs("    Public Function eva(Of T)(ByRef x As T, ByVal y As T) As Boolean\n", fo);
        eva1(fo);
        fputs("    Public Function eva(Of T)(ByRef x As T, ByVal y As _do(Of T)) As Boolean\n", fo);
        eva2(fo);
        fputs("    Public Function eva(Of T)(ByRef x As T, ByVal y As Func(Of T)) As Boolean\n", fo);
        eva2(fo);
        fputs("    Public Function eva(Of T)(ByVal x As _pointer(Of T), ByVal y As T) As Boolean\n", fo);
        eva3(fo);
        fputs("    Public Function eva(Of T)(ByVal x As _pointer(Of T), ByVal y As _do(Of T)) As Boolean\n", fo);
        eva4(fo);
        fputs("    Public Function eva(Of T)(ByVal x As _pointer(Of T), ByVal y As Func(Of T)) As Boolean\n", fo);
        eva4(fo);

        fputs("End Module\n", fo);
        fclose(fo);
    }
}

